﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using common4gp;
using System.Diagnostics.Contracts;

namespace wpf4gp.Helpers
{

    /// <summary>
    /// Delegate command
    /// </summary>
    public class DelegateCommand : ICommand
    {

        /// <summary>
        /// Event raised when changes the CanExecute property
        /// </summary>
        public event EventHandler CanExecuteChanged
        {
            add 
            { 
                CommandManager.RequerySuggested += value; 
            }
            remove 
            { 
                CommandManager.RequerySuggested -= value; 
            }
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="command"><see cref="System.Action"/> to execute</param>
        /// <param name="canExecute">Function for know if the command can run or not</param>
        public DelegateCommand(Action command, Func<bool> canExecute = null)
        {
            Contract.Requires<ArgumentNullException>(command.IsNotNull());
            _canExecute = canExecute;
            Command = command;
        }

        /// <summary>
        /// <see cref="System.Action"/> to execute
        /// </summary>
        private Action Command { get; set; }

        /// <summary>
        /// Execute the specified command
        /// </summary>
        /// <param name="parameter">Parameter to passo the Action</param>
        public void Execute(object parameter)
        {
            Command();
        }

        /// <summary>
        /// <see cref="System.Func"/> for know if the command can run
        /// </summary>
        private Func<bool> _canExecute { get; set; }

        /// <summary>
        /// <see cref="System.Bool"/> for know if the command can run
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns>True if the command can run</returns>
        public bool CanExecute(object parameter)
        {
            Contract.Ensures(Contract.Result<bool>().IsNotNull());
            return _canExecute.IsNull() || _canExecute();
        }

    }
}
